/*! @file main.cu
 *        @brief main : Benchmark driver routine
		  @brief: THIS CODE IS DEVELOPED AS PART OF MSc DISSERTATION  @ EPCC, 2011
*/

/*Header Include: Data structure and Benchmark routines */
#include "headers.h"
#include "data_structures.h"
#include "utils.h"
#include "solver_benchmark.h"
#include "conversion_benchmark.cu"

/** @fn int main(int argc, char *argv[])
 *     @brief main : Start of program, depends upon user choice call to CUSP matrix conversion 
 *     		     benchmark or CUSP ietrative solver benchmark!
*/             
int main(int argc, char * argv[])
{

	printf("\n ==================== CUSP LIBRARY BENCHMARK %s ==================== \n", BENCHMARK_VERSION);

	/*Two parametrs sufficient for Conversion Benchmark*/
	if ( argc == 2)
	{
		CONVERSION_BENCHMARK = 1;
	}
	/*For solver benchmark: need 5 parameters*/
	else if (argc >= 6)
	{
		CONVERSION_BENCHMARK  = 1;
		SOLVER_BENCHMARK = 1;
	}
	else
	{
		printf("\nFOR CONVERSION BENCHMARK: RUN AS:  ./benchmark matrix_market.mtx\n");
		printf("\nFOR SOLVER BENCHMARK:     RUN AS:  ./benchmark matrix_market.mtx tolerance max_it restart_at_count is_verbose(true/false) vec_b.mtx(optional) \n\n");
        exit(0);
	}
	
	/* Check command line arguments from user and set appropriate options*/
	parse_cmd_args(argc, argv);
	print_input_options();
	
	/* Set Up matrix from Matrix Market file that user has provided */
	setup_A();

	/* Setup RHS i.e. vector b for Ax = b */
	setup_b(A_Host.num_rows);


	/* If we want to benchmark only CUSP matrix conversion cost */
	if(CONVERSION_BENCHMARK)
	{
		printf("\n =========  CALCULATING CONVERSION COST FOR MATRIX : %s  ===========\n\n", input_options.mat_A_file);
		/* benchmark the cost of conversion sparse matrices on the host as well as device */
		matrix_conversion_benchmark();
	}
	
	if(SOLVER_BENCHMARK)
	{
		printf("\n\n\n=========  CALCULATING SOLVER PERFORMANCE FOR MATRIX : %s  ===========\n", input_options.mat_A_file);
		/* benchmark the performance of solver on host and device */
		cusp_solver_benchmark();
	}
	
	/* Flush output stream and exit the program */
	fflush(stdout);
	return 0;
}

